package com.shoping.common.health;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.Status;
import org.springframework.boot.context.event.*;
import org.springframework.context.ApplicationListener;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;

@Slf4j
@Order(Ordered.HIGHEST_PRECEDENCE)
public class WebApplicationListener implements ApplicationListener<SpringApplicationEvent>, EnvironmentAware {

    private Environment environment;

    @Autowired
    private SpringHealthIndicator healthIndicator;

    @Autowired
    private HealthStatusChecker healthStatusChecker;

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }

    public WebApplicationListener() {
    }

    @Override
    public void onApplicationEvent(SpringApplicationEvent event) {
        if (event instanceof ApplicationPreparedEvent) {
            healthIndicator.prepared();
            log.info("应用已准备就绪 - prepared!");
            return;
        }

        if (event instanceof ApplicationStartingEvent) {
            log.info("应用启动中 - starting!");
            healthIndicator.starting();
            return;
        }

        if (event instanceof ApplicationStartedEvent) {
            log.info("应用启动完成 - started!");
            healthIndicator.started();
            return;
        }

        boolean debug = environment.getProperty("debug", Boolean.class, false);

        //只有容器彻底成功后才会接受请求
        if (event instanceof ApplicationReadyEvent) {
            log.info("应用启动成功 - ready，服务就绪已开始运行!" + Constants.STD_EOF);
            healthIndicator.ready();
            if (!debug) {
                log.info(">>>>>>>>>> 控制台输出结束（如果希望控制台继续输出，请打开debug模式） <<<<<<<<<<");
            }
            System.out.println(" ⢎⡑ ⡇⢸ ⡎⠑ ⡎⠑ ⣏⡉ ⢎⡑ ⢎⡑");
            System.out.println(" ⠢⠜ ⠣⠜ ⠣⠔ ⠣⠔ ⠧⠤ ⠢⠜ ⠢⠜");
            healthStatusChecker.open();
            Runtime.getRuntime().addShutdownHook(hook);
            return;
        }

        if (event instanceof ApplicationFailedEvent) {
            log.info("应用启动失败 - failed，进程即将退出!" + Constants.STD_EOF);
            healthIndicator.down();
            if (!debug) {
                log.info(">>>>>>>>>> 控制台输出结束（如果希望控制台继续输出，请打开debug模式） <<<<<<<<<<");
            }
        }
    }

    private final Thread hook = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                healthStatusChecker.suspend(Status.DOWN);
            } catch (Exception e) {
                //
            }
        }
    });
}
